package com.regex.web.config;

import java.util.HashMap;
import java.util.Map;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.regex.web.security.OAuth2ShiroRealm;


/**
 * Shiro 权限控制集成
 */
@Configuration
public class ShiroConfig {

    private static Logger logger = LoggerFactory.getLogger(ShiroConfig.class);

    public ShiroConfig() {
        logger.info("ShiroConfig Init...");
    }
    
    /**
     * 将自己的验证方式加入容器
     */
    @Bean
    public OAuth2ShiroRealm myShiroRealm() {
        OAuth2ShiroRealm OAuth2ShiroRealm = new OAuth2ShiroRealm();
        //启用缓存,默认false
        OAuth2ShiroRealm.setCachingEnabled(true);
        //  启用身份验证缓存，即缓存AuthenticationInfo信息，默认false；
        OAuth2ShiroRealm.setAuthenticationCachingEnabled(false);
        //  缓存AuthenticationInfo信息的缓存名称,即配置在ehcache.xml中的cache name
        OAuth2ShiroRealm.setAuthenticationCacheName("authenticationCache");
        //  启用授权缓存，即缓存AuthorizationInfo信息，默认false；
        OAuth2ShiroRealm.setAuthorizationCachingEnabled(true);
        //  缓存AuthorizationInfo信息的缓存名称；
        OAuth2ShiroRealm.setAuthorizationCacheName("authorizationCache");

        return OAuth2ShiroRealm;
    }

    /**
     * 权限管理，配置主要是Realm的管理认证
     */
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        //注入EhCacheManager缓存管理器
        securityManager.setCacheManager(ehCacheManager());
//        securityManager.setSessionManager(sessionManager());
        return securityManager;
    }
    
//    @Bean(name = "sessionManager")
//    public DefaultWebSessionManager sessionManager() {
//        System.out.println("ShiroConfiguration.sessionManager()");
//        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
//        sessionManager.getSessionIdCookie().setName("sId");
//        sessionManager.setGlobalSessionTimeout(3600000);
//        sessionManager.setDeleteInvalidSessions(true);
//        sessionManager.setSessionValidationScheduler(sessionValidationScheduler());
//        sessionManager.setSessionValidationSchedulerEnabled(true);
////      sessionManager.setSessionListeners(sessionListeners());
//        sessionManager.setSessionDAO(mySessionDao());
//        return sessionManager;
//    }
//    
//    @Bean
//    public EnterpriseCacheSessionDAO mySessionDao() {
//        System.out.println("ShiroConfiguration.mySessionDao()");
//        EnterpriseCacheSessionDAO mySessionDao = new EnterpriseCacheSessionDAO();
//        mySessionDao.setActiveSessionsCacheName("shiro-activeSessionCache");
////      mySessionDao.setSessionIdGenerator(sessionIdGenerator());
//        return mySessionDao;
//    }

    
//    @Bean
//  public Collection<SessionListener> sessionListeners() {
//      Collection<SessionListener> listeners = new ArrayList<>();
//      listeners.add(myShiroSessionListener());
//      return listeners;
//  }
//    
//    @Bean
//  public MyShiroSessionListener myShiroSessionListener() {
//      return new MyShiroSessionListener();
//  }

    /**
     * 加入注解的使用，不加入这个注解不生效
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
    
    @Bean
    public ExecutorServiceSessionValidationScheduler sessionValidationScheduler() {
        ExecutorServiceSessionValidationScheduler sessionValidationScheduler = new ExecutorServiceSessionValidationScheduler();
        sessionValidationScheduler.setInterval(3600000);
        return sessionValidationScheduler;
    }

    /**
     * 配置自定义的密码比较器
     */
//    @Bean(name = "credentialsMatcher")
//    public CredentialsMatcher credentialsMatcher() {
//        return new CredentialsMatcher();
//    }
    
    @Bean(name = "ehcacheManager")
    public EhCacheManager ehCacheManager() {
        logger.info("注入Shiro的缓存管理器-->ehCacheManager", EhCacheManager.class);
        EhCacheManager cacheManager = new EhCacheManager();
        cacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
        return cacheManager;
    }


    /**
     * Filter工厂，设置对应的过滤条件和跳转条件
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        Map<String, String> map = new HashMap<>();
        //对所有用户认证
        map.put("/sys/**", "authc");
        map.put("/main", "authc");
        map.put("/index", "authc");
        map.put("/", "authc");
        //不拦截URL
        map.put("/tologin", "anon");
        map.put("/static/**", "anon");
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }
    
    @Bean(name = "lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
    logger.info("ShiroConfiguration--lifecycleBeanPostProcessor");
    return new LifecycleBeanPostProcessor();
    }

}
